﻿/**

 * Copyright (c) 2015-2016, FastDev 刘强 (fastdev@163.com) & Quincy.

 *

 * Licensed under the Apache License, Version 2.0 (the "License");

 * you may not use this file except in compliance with the License.

 * You may obtain a copy of the License at

 *

 *      http://www.apache.org/licenses/LICENSE-2.0

 *

 * Unless required by applicable law or agreed to in writing, software

 * distributed under the License is distributed on an "AS IS" BASIS,

 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.

 * See the License for the specific language governing permissions and

 * limitations under the License.

 */


using ConsoleApplication1.Cluster.Entity;
using OF.DistributeService.Core.Common;
using OF.Notify.Channel;
using OF.Notify.Client;
using OF.Notify.DataHost;
using OF.Notify.DataHost.Cluster;
using OF.Notify.Entity;
using OF.Notify.Test;
using OF.Notify.TestWeb;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading;
using System.Threading.Tasks;

namespace Mock
{
    public class Program
    {
        public static void Main(string[] args)
        {
            AppDomain.CurrentDomain.UnhandledException += CurrentDomain_UnhandledException;
            TaskScheduler.UnobservedTaskException += (sender, targs) => Util.LogException("UnobservedTaskException", targs.Exception);
            TestMessage();
         }

        private static void TestMessage()
        {
            //Productor.Init(new NotifyServiceProvider());
            //TestWebHost.CheckPerfromance(1024 * 10);
            //TestTwoTopic.CheckClusterCrash1();
            //TestSwitchCluster.TestSwitch();
            ///TestOneTopicPerformance.TestPerformance();
            //TestLinkHead.Test();
            //estTwoTopic3RongYu.SendMessageWithClusterChange();
            //TestTwoTopic.CheckClusterCrash6();
            //TestIEnumerable.Test();
            //TestMultiTask.Test();
            //TestOneTopic.SendMessageWithClusterChange();
            TestTwoTopic.SendMessageWithClusterChange();
            //TestOneTopicPerformance.CheckSendMessages(500);
            //TestWebHost.CheckSendMessages(500);
            //TestTwoTopic.SendMessageWithClusterChange();
        }


        public class TestIEnumerable
        {
            private static List<int> arr = new List<int> { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10};
            public static IEnumerable<int> Get()
            {
                for (int i1 = 0; i1 < arr.Count; i1++)
                {
                    Console.WriteLine("return :" + arr[i1]);
                    yield return i1;
                }
            }

            public static int TestSwitch(string str)
            {
                int ret = 0;
                switch (str)
                { 
                    case "a":
                        ret = 1;
                        break;
                    case "b":
                        ret = 2;
                        break;
                    default:
                        ret = 3;
                        break;
                }
                return ret;
            }

            public static int TestSwitch(int str)
            {
                int ret = 0;
                switch (str)
                {
                    case 1:
                        ret = 1;
                        break;
                    case 2:
                        ret = 2;
                        break;
                    default:
                        ret = 3;
                        break;
                }
                return ret;
            }
            public static void Test()
            {
                Thread th = new Thread(new ThreadStart(() => {
                    while (true)
                    {
                        Thread.Sleep(1000);
                        arr.Add(arr.Count + 1);
                        arr.RemoveAt(arr.Count - 10);
                    }
                }));
                th.Start();
                foreach (var item in Get())
                {
                    Console.WriteLine("visit " + item);
                    Thread.Sleep(1000);
                }
                Console.Read();
            }
        }

        public class TestMultiTask
        { 
            public static void Test()
            {
                TaskFactory syncTaskFactory = new TaskFactory(new LimitedConcurrencyLevelTaskScheduler(3));
                for (int i1 = 0; i1 < 10; i1++)
                {
                    syncTaskFactory.StartNew((oI1) => {
                        int pI1 = (int)oI1;
                        Util.LogInfo("Start thread " + Thread.CurrentThread.ManagedThreadId + "," + pI1);
                        Thread.Sleep(2000);
                        Util.LogInfo("End thread " + Thread.CurrentThread.ManagedThreadId + "," + pI1);
                    }, i1);
                }
                Console.WriteLine("All task finished!");
                Console.ReadLine();
            }
        }

        public class TestTopicMessage
        {
            public byte topicEnum;
            public byte[] body;

            public TestTopicMessage(byte topicEnum, byte[] body)
            {
                this.topicEnum = topicEnum;
                this.body = body;
            }

            public byte[] GetContent()
            {
                byte[] result = new byte[body.Length + 1];
                result[0] = (byte)topicEnum;
                Array.Copy(body, 0, result, 1, body.Length);
                return result;
            }

            public static TestTopicMessage Parse(byte[] content)
            {
                byte[] body = new byte[content.Length - 1];
                Array.Copy(content, 1, body, 0, body.Length);
                TestTopicMessage message = new TestTopicMessage((byte)content[0], body);
                return message;
            }
        }

        private static void TestMergeNode()
        {
            var mergedResult = MyMergeClusterNodeMappings(new List<SmallValue16AndFlag> { 
                new SmallValue16AndFlag { Status = SmallValue16AndFlagStatus.Synced, Value = 2 },
                new SmallValue16AndFlag { Status = SmallValue16AndFlagStatus.Synced, Value = 1 },
                new SmallValue16AndFlag { Status = SmallValue16AndFlagStatus.Syncing, Value = 1 },
                new SmallValue16AndFlag { Status = SmallValue16AndFlagStatus.Deleted, Value = 2 },
                new SmallValue16AndFlag { Status = SmallValue16AndFlagStatus.Syncing, Value = 2 },
                new SmallValue16AndFlag { Status = SmallValue16AndFlagStatus.Deleted, Value = 1 },

                                new SmallValue16AndFlag { Status = SmallValue16AndFlagStatus.Syncing, Value = 3 },
                new SmallValue16AndFlag { Status = SmallValue16AndFlagStatus.Deleted, Value = 4 },
                new SmallValue16AndFlag { Status = SmallValue16AndFlagStatus.Syncing, Value = 4 },
                new SmallValue16AndFlag { Status = SmallValue16AndFlagStatus.Deleted, Value = 3 },
            });
            Util.LogInfo(string.Join(" ", mergedResult.Select(node => node.Value + ":" + node.Status)));
            Console.Read();
        }

        private static List<SmallValue16AndFlag> MyMergeClusterNodeMappings(List<SmallValue16AndFlag> allIds)
        {
            allIds = allIds.OrderBy(item => item.GetOrderValue()).ToList();
            SmallValue16AndFlag lastItem = null;
            List<SmallValue16AndFlag> mergedList = new List<SmallValue16AndFlag>(allIds.Count);
            foreach (var item in allIds)
            {
                if (lastItem == null)
                {
                }
                else
                {
                    if (lastItem.Value == item.Value)
                    {

                    }
                    else
                    {
                        mergedList.Add(lastItem);
                    }
                }
                lastItem = item;
            }
            if (lastItem != null)
            {
                mergedList.Add(lastItem);
            }
            return mergedList;
        }

        private static void TestList()
        {
            var list = new List<int> { 1, 2, 3, 2, 4 };
            Util.LogInfo(string.Join(" ", GetSenderMoveToLastList(1, list)));
            Util.LogInfo(string.Join(" ", GetSenderMoveToLastList(2, list)));
            Util.LogInfo(string.Join(" ", GetSenderMoveToLastList(5, list)));
            Console.Read();
        }
        private static List<int> GetSenderMoveToLastList(int id, List<int> list)
        {
            var thisProxyList = list.Where(proxy => proxy == id).ToList();
            if (thisProxyList == null || thisProxyList.Count() <= 0)
            {
                return list;
            }
            else
            {
                list = list.ToList();
                foreach (var thisProxy in thisProxyList)
                {
                    list.Remove(thisProxy);
                }
                list.AddRange(thisProxyList);
                return list;
            }
        }

        static void CurrentDomain_UnhandledException(object sender, UnhandledExceptionEventArgs e)
        {
            Util.LogException("UnhandledException", e.ExceptionObject as Exception);
        }

    }



}
